import datetime
import logging
import sys

from absl import app, flags

import numpy
import pandas

import coin.strategy.mm.tool.archive_base as abase
from coin.strategy.mm.tool.lm_signal_base import (dump_lm_signal, get_lm_product)

FLAGS = flags.FLAGS


class SignalStatJob(object):
  def __init__(self, trading_date, time_range, profile):
    self.trading_date = trading_date
    self.time_range = time_range
    self.profile = profile
    self.product = get_lm_product(self.profile, self.trading_date)

  def run(self):
    signals = dump_lm_signal(self.profile, self.trading_date, self.time_range)
    print(pandas.DataFrame(signals).signal.quantile(numpy.arange(0, 1, 0.1)))


def dump_signal_book(trading_date, time_range, profile):
  align_job = SignalStatJob(trading_date, time_range, profile)
  align_job.run()


def launch_multi(trading_dates, time_range, profile):
  if len(trading_dates) == 1:
    dump_signal_book(trading_dates[0], time_range, profile)
  else:
    from concurrent.futures import ProcessPoolExecutor
    futures = []
    with ProcessPoolExecutor(max_workers=5) as executor:
      for trading_date in trading_dates:
        futures.append(executor.submit(dump_signal_book, trading_date, time_range, profile))
    for future in futures:
      future.result()


def get_trading_dates(trading_date_str):
  if trading_date_str.find("-") >= 0:
    tdfrom, tdto = trading_date_str.split("-")
    return pandas.date_range(tdfrom, tdto).to_pydatetime()
  else:
    return [datetime.datetime.strptime(trading_date_str, '%Y%m%d')]


def main(_):
  baseflags = abase.get_base_flags()
  trading_dates = abase.get_trading_dates(baseflags.trading_date)
  profile = FLAGS.profile
  assert profile, '--profile must be specified.'
  sys.stdout.flush()
  launch_multi(trading_dates=trading_dates, time_range=baseflags.time_range, profile=profile)


if __name__ == '__main__':
  abase.define_base_flags()
  abase.define_feed_archive_flags()

  flags.DEFINE_string('profile', None, '')

  logging.basicConfig(level='DEBUG', format='%(levelname)8s %(asctime)s %(name)s] %(message)s')
  app.run(main)
